package com.sgcc.nfc.lock.presentation.rooms

import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.sgcc.nfc.lock.R
import com.sgcc.nfc.lock.core.location.CoordinateConverter
import com.sgcc.nfc.lock.databinding.FragmentRoomDetailBinding
import com.sgcc.nfc.lock.domain.model.Lock
import com.sgcc.nfc.lock.presentation.locks.LockAdapter
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch

@AndroidEntryPoint
class RoomDetailFragment : Fragment() {

    private var _binding: FragmentRoomDetailBinding? = null
    private val binding get() = _binding!!
    private val viewModel: RoomDetailViewModel by viewModels()
    private val lockAdapter = LockAdapter(::onLockClicked)

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentRoomDetailBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.roomLockRecycler.apply {
            layoutManager = LinearLayoutManager(requireContext())
            adapter = lockAdapter
        }
        binding.editButton.setOnClickListener {
            val bundle = Bundle().apply { putLong(RoomFormViewModel.KEY_ROOM_ID, viewModel.currentRoomId()) }
            findNavController().navigate(R.id.roomFormFragment, bundle)
        }
        binding.deleteButton.setOnClickListener { confirmDelete() }
        binding.openMapButton.setOnClickListener { startNavigation() }
        observeNavigationResults()
        observeViewModel()
    }

    private fun observeViewModel() {
        viewModel.room.observe(viewLifecycleOwner) { room ->
            if (room != null) {
                binding.roomName.text = room.roomName
                
                // 更新状态芯片
                binding.roomStatusChip.apply {
                    text = when (room.status) {
                        com.sgcc.nfc.lock.domain.model.RoomStatus.NORMAL -> getString(R.string.room_status_safe)
                        com.sgcc.nfc.lock.domain.model.RoomStatus.IN_USE -> getString(R.string.room_status_in_use)
                        com.sgcc.nfc.lock.domain.model.RoomStatus.ALERT -> getString(R.string.room_status_alert)
                        com.sgcc.nfc.lock.domain.model.RoomStatus.UNKNOWN -> getString(R.string.lock_status_unknown)
                    }
                    
                    // 设置芯片颜色
                    val colorRes = when (room.status) {
                        com.sgcc.nfc.lock.domain.model.RoomStatus.NORMAL -> R.color.color_status_success
                        com.sgcc.nfc.lock.domain.model.RoomStatus.IN_USE -> R.color.color_status_warning
                        com.sgcc.nfc.lock.domain.model.RoomStatus.ALERT -> R.color.color_status_error
                        com.sgcc.nfc.lock.domain.model.RoomStatus.UNKNOWN -> android.R.color.darker_gray
                    }
                    chipBackgroundColor = ContextCompat.getColorStateList(requireContext(), colorRes)
                    setTextColor(ContextCompat.getColor(requireContext(), android.R.color.white))
                }
                
                // 保持旧的TextView设置以保持兼容性
                binding.roomStatus.text = when (room.status) {
                    com.sgcc.nfc.lock.domain.model.RoomStatus.NORMAL -> getString(R.string.room_status_safe)
                    com.sgcc.nfc.lock.domain.model.RoomStatus.IN_USE -> getString(R.string.room_status_in_use)
                    com.sgcc.nfc.lock.domain.model.RoomStatus.ALERT -> getString(R.string.room_status_alert)
                    com.sgcc.nfc.lock.domain.model.RoomStatus.UNKNOWN -> getString(R.string.lock_status_unknown)
                }
                
                binding.roomRegion.text = room.regionName ?: "-"
                binding.roomAddress.text = room.address ?: "-"
                binding.roomCoordinates.text = if (room.latitude != null && room.longitude != null) {
                    getString(R.string.room_coordinates_format, room.latitude, room.longitude)
                } else {
                    getString(R.string.room_location_unavailable)
                }
                binding.roomCounts.text = getString(R.string.dashboard_total_locks, room.lockCount)
                lockAdapter.submitList(room.locks)
            }
        }
        viewModel.isLoading.observe(viewLifecycleOwner) { binding.roomDetailLoading.isVisible = it }
        viewModel.error.observe(viewLifecycleOwner) { error ->
            error?.let { Snackbar.make(binding.root, it, Snackbar.LENGTH_LONG).show() }
        }
        viewLifecycleOwner.lifecycleScope.launchWhenStarted {
            viewModel.events.collect { event ->
                when (event) {
                    is RoomDetailEvent.ShowMessage -> Snackbar.make(binding.root, event.message, Snackbar.LENGTH_LONG).show()
                    RoomDetailEvent.Deleted -> {
                        Snackbar.make(binding.root, getString(R.string.room_delete_success), Snackbar.LENGTH_SHORT).show()
                        notifyListChanged()
                        findNavController().popBackStack()
                    }
                }
            }
        }
    }

    private fun observeNavigationResults() {
        findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<Boolean>(RoomFormFragment.RESULT_KEY_ROOM_UPDATED)?.observe(
            viewLifecycleOwner
        ) { updated ->
            if (updated == true) {
                viewModel.loadDetail()
                notifyListChanged()
                findNavController().currentBackStackEntry?.savedStateHandle?.remove<Boolean>(RoomFormFragment.RESULT_KEY_ROOM_UPDATED)
            }
        }
    }

    private fun onLockClicked(lock: Lock) {
        val bundle = Bundle().apply { putLong("lockId", lock.lockId) }
        findNavController().navigate(R.id.lockDetailFragment, bundle)
    }

    private fun startNavigation() {
        val room = viewModel.room.value ?: return
        val lat = room.latitude
        val lng = room.longitude
        if (lat == null || lng == null) {
            Snackbar.make(binding.root, R.string.room_location_unavailable, Snackbar.LENGTH_LONG).show()
            return
        }
        val destinationName = room.roomName?.takeIf { it.isNotBlank() } ?: getString(R.string.room_navigation_destination_default)
        val options = buildNavigationOptions(destinationName, lat, lng)
        if (options.isEmpty()) {
            Snackbar.make(binding.root, R.string.room_navigation_no_app, Snackbar.LENGTH_LONG).show()
            return
        }
        if (options.size == 1) {
            launchNavigation(options.first())
            return
        }
        MaterialAlertDialogBuilder(requireContext())
            .setTitle(R.string.room_navigation_choose_app)
            .setItems(options.map { it.label }.toTypedArray()) { _, index ->
                options.getOrNull(index)?.let { launchNavigation(it) }
            }
            .show()
    }

    private fun launchNavigation(option: NavigationOption) {
        runCatching { startActivity(option.intent) }
            .onFailure {
                Snackbar.make(binding.root, R.string.room_navigation_no_app, Snackbar.LENGTH_LONG).show()
            }
    }

    private fun buildNavigationOptions(name: String, latitude: Double, longitude: Double): List<NavigationOption> {
        val context = requireContext()
        val pm = context.packageManager
        val encodedName = Uri.encode(name)
        val options = mutableListOf<NavigationOption>()

        if (isAppInstalled(pm, "com.autonavi.minimap")) {
            val uri = Uri.parse("amapuri://route/plan/?dlat=$latitude&dlon=$longitude&dname=$encodedName&dev=0&t=0")
            val intent = Intent(Intent.ACTION_VIEW, uri).apply { setPackage("com.autonavi.minimap") }
            options += NavigationOption(getString(R.string.room_navigation_app_amap), intent)
        }

        if (isAppInstalled(pm, "com.baidu.BaiduMap")) {
            val (bdLat, bdLng) = CoordinateConverter.gcj02ToBd09(latitude, longitude)
            val uri = Uri.parse("baidumap://map/direction?destination=latlng:$bdLat,$bdLng|name:$encodedName&mode=driving")
            val intent = Intent(Intent.ACTION_VIEW, uri).apply { setPackage("com.baidu.BaiduMap") }
            options += NavigationOption(getString(R.string.room_navigation_app_baidu), intent)
        }

        if (isAppInstalled(pm, "com.tencent.map")) {
            val uri = Uri.parse("qqmap://map/routeplan?type=drive&tocoord=$latitude,$longitude&to=$encodedName")
            val intent = Intent(Intent.ACTION_VIEW, uri).apply { setPackage("com.tencent.map") }
            options += NavigationOption(getString(R.string.room_navigation_app_tencent), intent)
        }

        if (isAppInstalled(pm, "com.google.android.apps.maps")) {
            val query = Uri.encode("$latitude,$longitude ($name)")
            val uri = Uri.parse("google.navigation:q=$query&mode=d")
            val intent = Intent(Intent.ACTION_VIEW, uri).apply { setPackage("com.google.android.apps.maps") }
            options += NavigationOption(getString(R.string.room_navigation_app_google), intent)
        }

        if (options.isEmpty()) {
            val geoUri = Uri.parse("geo:$latitude,$longitude?q=$latitude,$longitude($encodedName)")
            val geoIntent = Intent(Intent.ACTION_VIEW, geoUri)
            if (geoIntent.resolveActivity(pm) != null) {
                options += NavigationOption(getString(R.string.room_navigation_app_generic), geoIntent)
            }
        }

        return options
    }

    private fun isAppInstalled(packageManager: PackageManager, packageName: String): Boolean =
        runCatching {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0))
            } else {
                @Suppress("DEPRECATION")
                packageManager.getPackageInfo(packageName, 0)
            }
        }.isSuccess

    private data class NavigationOption(val label: String, val intent: Intent)

    private fun confirmDelete() {
        MaterialAlertDialogBuilder(requireContext())
            .setTitle(R.string.room_delete_confirm)
            .setMessage(R.string.room_delete_confirm_message)
            .setNegativeButton(R.string.common_cancel, null)
            .setPositiveButton(R.string.common_delete) { _, _ -> viewModel.deleteRoom() }
            .show()
    }

    private fun notifyListChanged() {
        findNavController().previousBackStackEntry?.savedStateHandle?.set(RoomFormFragment.RESULT_KEY_ROOM_UPDATED, true)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}
